package com.ruoyi.project.system.controller;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.utils.sign.Md5Utils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.framework.aspectj.lang.annotation.Anonymous;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.redis.RedisCache;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.page.TableDataInfo;
import com.ruoyi.project.monitor.domain.TeamOrder;
import com.ruoyi.project.system.domain.SysQuery;
import com.ruoyi.project.system.domain.SysQueryPay;
import com.ruoyi.project.system.mapper.SysEarningsMapper;
import com.ruoyi.project.system.mapper.SysExtractMapper;
import com.ruoyi.project.system.mapper.SysQueryPayMapper;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.project.system.service.ISysQueryPayService;
import com.ruoyi.project.system.service.ISysQueryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 进件查询支付Controller
 */
@Slf4j
@RestController
@RequestMapping("/pay")
public class SysQueryPayController extends BaseController {

    @Autowired
    private ISysQueryPayService sysQueryPayService;

    @Autowired
    private ISysQueryService sysQueryService;

    @Autowired
    private SysQueryPayMapper sysQueryPayMapper;

    @Autowired
    private SysEarningsMapper sysEarningsMapper;

    @Autowired
    private SysExtractMapper sysExtractMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private RedisCache redisCache;

    @Anonymous
    @GetMapping("/wxpay")
    public Boolean wxpay(@NotNull Long id) {
        SysQuery sysQuery = sysQueryService.selectSysQueryById(id);
        return sysUserMapper.queryUserWxpayh5(sysQuery.getUserId()) == 0;
    }

    /**
     * 新增进件查询支付
     */
    @PostMapping
    @Anonymous
    public AjaxResult add(@RequestBody SysQueryPay sysQueryPay) {
        if (sysQueryPay.getQueryId() == null || sysQueryPay.getUserId() == null) {
            return error("缺少必须参数");
        }
        String key = CacheConstants.PAY_FREQUENCY + sysQueryPay.getUserId();
        if (redisCache.hasKey(key)) {
            return AjaxResult.error("发起支付频率过高！等" + redisCache.getExpire(key) + "秒");
        } else {
            redisCache.setCacheObject(key, "_", 20, TimeUnit.SECONDS);
        }

        sysQueryPay.setOrderNo("RYC2" + IdUtils.fastSimpleUUID().substring(0, 8).toUpperCase());
        try {
            JSONObject payInfo = sysQueryPayService.createPayInfo(sysQueryPay);
            payInfo.put("orderNo", sysQueryPay.getOrderNo());
            return success(payInfo);
        } catch (Exception e) {
            e.printStackTrace();
            return error("发起支付异常！");
        }
    }

    @Anonymous
    @GetMapping("/state")
    public Map<String, Object> state(@NotNull Long id) {
        return sysQueryPayMapper.payState(id);
    }

    /**
     * 修改支付订单(回调)
     */
    @Anonymous
    @GetMapping("/notify")
    public String notify(@RequestParam Map<String, String> map) {
        log.info("支付返回：" + map);
        if (map.isEmpty()) {
            return "err";
        }
        // 检证数据
        String str = map.get("state") + "1394150425178931200" + map.get("orderNo") + map.get("amount") + "086951d2cdb0b467c553b507d6f866db";       // 容易查
        String sign = Md5Utils.hash(str);
        if (!sign.equalsIgnoreCase(map.get("sign"))) {
            return "err";
        }
        // 您的代码块 start
        SysQueryPay sqp = sysQueryPayService.selectSysQueryPayByOrderNo(map.get("orderNo"));
        if (sqp != null && "SUCCESS".equals(sqp.getPayState())) {
            return "success";
        }
        if ("1".equals(map.get("state"))) {         //支付成功
            // 短信通知
            AsyncManager.me().execute(AsyncFactory.report(sqp));
            //2.修改订单支付状态信息
            int update = sysQueryPayService.updateSysQueryPay(new SysQueryPay(
                    map.get("orderNo"),
                    map.get("actualPayAmount"),
                    map.get("platformOrderNo"),
                    "SUCCESS",
                    DateUtils.parseDate(map.get("payTime"))
            ));
            return update == 1 ? "success" : "fail";
        } else {
            return "fail";
        }
    }

    /**
     * 退款
     */
    @GetMapping("/refund")
    public AjaxResult refund(SysQueryPay sysQueryPay) throws Exception {
        sysQueryPay.setRemark("REFUND:" + IdUtils.fastSimpleUUID().substring(0, 9).toUpperCase());
        return toAjax(sysQueryPayService.refund(sysQueryPay));
    }

    @GetMapping("/srmxList")
    public AjaxResult querySrmxList(Long userId) {
        if (userId == null) {
            return warn("缺少参数");
        }
        return success(sysQueryPayMapper.srmxList(userId));
    }

    /**
     * 获取我的合计统计
     */
    @GetMapping("/rankingList")
    public AjaxResult rankingList() {
        List<Map<String, Object>> list = sysQueryPayMapper.rankingList();

        for (Map<String, Object> m : list) {
            String nn = m.get("NN").toString();
            int l = nn.length();
            if (l < 2) {
                m.replace("NN", "***" + nn);
            } else {
                m.replace("NN", "***" + nn.substring(l - 1));
            }

        }
        return success(list).put("date", DateUtils.getTime());
    }

    /**
     * 获取我的合计统计
     */
    @GetMapping("/sum")
    public AjaxResult sumEarnings() {
        AjaxResult ajaxResult = new AjaxResult();
        ajaxResult.put("sy_yj", sysQueryPayMapper.sumBrokerage(SecurityUtils.getUserId()));
        ajaxResult.put("sy_tc", sysQueryPayMapper.sumRoyaltyByParent(SecurityUtils.getUserId()));
        ajaxResult.put("sy_hbqt", sysEarningsMapper.sumEarningsByUserId(SecurityUtils.getUserId()));
        ajaxResult.put("tx", sysExtractMapper.sumExtractByUserId(SecurityUtils.getUserId()));
        ajaxResult.put("tk_xjdl", sysQueryPayMapper.sumRoyaltyRefund(SecurityUtils.getUserId()));
        ajaxResult.put("tk_yj", sysQueryPayMapper.sumBrokerageRefund(SecurityUtils.getUserId()));
        return ajaxResult;
    }

    @GetMapping("/redPacketCount")
    public AjaxResult redPacketCount() {
        return AjaxResult.success(sysQueryPayMapper.redPacketCount(SecurityUtils.getUserId()));
    }

    @GetMapping("/count")
    public AjaxResult queryCount() {
        return AjaxResult.success(sysQueryPayMapper.selectSuccessPayCount(SecurityUtils.getUserId()));
    }

    @GetMapping("/teamStatis")
    public AjaxResult teamStatis() {
        AjaxResult ajaxResult = AjaxResult.success();
        ajaxResult.put("rs", sysQueryPayMapper.groupCount(SecurityUtils.getUserId()));
        Float zsr_ztyj = sysQueryPayMapper.sumBrokerage(SecurityUtils.getUserId());
        Map<String, Double> groupIncome = sysQueryPayMapper.groupIncome(SecurityUtils.getUserId());

        ajaxResult.put("zsr_tc", zsr_ztyj + groupIncome.get("header_tc"));
        ajaxResult.put("zsr", zsr_ztyj + groupIncome.get("header_tc") + groupIncome.get("team_yj"));
        return ajaxResult;
    }

    @GetMapping("/teamOrders")
    public TableDataInfo teamOrders(TeamOrder teamOrder) {
        teamOrder.setUserId(SecurityUtils.getUserId());
        startPage();
        List<Map<String, String>> teamOrders = sysQueryPayMapper.groupOrders(teamOrder);
        return getDataTable(teamOrders);
    }

    @GetMapping("/statistic/{productId}")
    public AjaxResult statistic(@PathVariable("productId") String productId) {
        return success(sysQueryPayMapper.statistic(SecurityUtils.getUserId(), productId));
    }

    /**
     * 查询进件查询支付列表
     */
    @GetMapping("/list")
    public TableDataInfo list(SysQueryPay sysQueryPay) {
        sysQueryPay.setDelSign("0");
        startPage();
        List<SysQueryPay> list = sysQueryPayService.selectSysQueryPayList(sysQueryPay);

        for (SysQueryPay cr : list) {
            String kw = cr.getKeyword();
            int l = kw.length() - 11;
            int i = kw.indexOf("::") + 2;
            StringBuffer sb = new StringBuffer(cr.getKeyword());
            sb.replace(l, l + 3, "***");
            sb.replace(i, i + 3, "***");
            cr.setKeyword(sb.toString());
        }
        return getDataTable(list);
    }

    @GetMapping("/listCom")
    public TableDataInfo listCom(SysQueryPay sysQueryPay) {

        startPage();
        List<SysQueryPay> list = sysQueryPayService.selectSysQueryPayList(sysQueryPay);

        for (SysQueryPay cr : list) {
            String kw = cr.getKeyword();
            int i = kw.indexOf("::");
            if (i != -1) {
                cr.setKeyword(kw.substring(0, i));
            }
        }
        return getDataTable(list);
    }

    /**
     * 导出进件查询支付列表
     */
    @PreAuthorize("@ss.hasPermi('system:pay:export')")
    @Log(title = "进件查询支付", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, SysQueryPay sysQueryPay) {
        List<SysQueryPay> list = sysQueryPayService.selectSysQueryPayList(sysQueryPay);
        ExcelUtil<SysQueryPay> util = new ExcelUtil<SysQueryPay>(SysQueryPay.class);
        util.exportExcel(response, list, "进件查询支付数据");
    }

    /**
     * 获取进件查询支付详细信息
     */
    @Anonymous
    @GetMapping(value = "/{orderNo}")
    public AjaxResult getInfo(@PathVariable("orderNo") String orderNo) {
        return success(sysQueryPayService.selectSysQueryPayByOrderNo(orderNo));
    }

    /**
     * 修改进件查询支付
     */
    @PreAuthorize("@ss.hasPermi('system:pay:edit')")
    @Log(title = "进件查询支付", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SysQueryPay sysQueryPay) {
        return toAjax(sysQueryPayService.updateSysQueryPay(sysQueryPay));
    }

}
